import sys
import re

TCRAna1 = sys.argv[1]  #all TCRs table(barcode,TCR/BCRid). XAXB is ok,it will choose.
CellListFile = sys.argv[2] #if not ,fill in F.Only consider these barcode
sampleName = sys.argv[3]
workdir = sys.argv[4]
XCRFlag = sys.argv[5] #1,TCR;2,BCR
XCRSeqFile = sys.argv[6] #if not, fill in "F"

# TCRAna1 = "/home/hsmy/mob/p.TCRinfo1.xls"
# CellListFile = "/home/hsmy/mob/p.Barcode.txt"
# sampleName = "p"
# workdir = "/home/hsmy/mob"
# XCRFlag = "1" #1,TCR;2,BCR
# XCRSeqFile = "/home/hsmy/mob/p.RawTCRSeq.fa" #if not, fill in "F"

# finish in 2020.6.3
# log:TCR MChainList:['TRAV38:CPRGFGNEKLTF', 'TRAV38:CAYRCPRGFGNEKLTF']

# output:
# TCRTBelong.xls,SCTCRBelong.xls,TCRAna2.xls,BarTCRInfo.xls/BCR
# maybe output:
# XCRFaSeq.xls(TCR,TCRindex,ChoBar,ChainInfo,RawSeq)

# if normal TCR too small,then single Chain TCR not map! so final barcode is too small!
# !!!2021.2.24,if SCTCR not map,then drop. so finally table's barcode would less then raw TCR info's.

# XCR flag
if XCRFlag == "1":
    XCR = "TCR"
elif XCRFlag == "2":
    XCR = "BCR"
else:
    XCR = "TCR"


# XCR flag end.


# base function

def CombMulWords(WordsList, sep):
    stri = ""
    for i in WordsList:
        stri += str(i)
        stri += sep
    stri = stri.strip(sep)
    return stri


def SearchChainInfo(BarChainDict, VGene):
    SVflag = 0
    for x in BarChainDict:
        for y in BarChainDict[x]:
            if y.find(VGene) > -1:
                return y

    if SVflag == 0:
        print "can't find VGene!", BarChainDict, VGene
        return False


def getTRABVFa(inputFa, BFlag):
    # input:
    # inputFa:a file path!
    # Fafile format(>TRAV1-1\n1 AAAA)
    # output:geneFaDict

    import re
    print "from fa file get TRAV/TRBV fa..."
    geneFaDict = {}

    LineNum = -1
    GeneSeq = ""
    geneName = "NA"
    geneFaDict[geneName] = ""

    f = open(inputFa)
    line = f.readline()
    while line:
        line = line.strip("\n")
        m = re.match("(>)(\S*)", line)
        n = re.match("(\d+)(\s+)(\S+)", line)
        if m:
            geneFaDict[geneName] = GeneSeq  # save before Gene seq

            geneName = m.group(2)
            if geneName not in geneFaDict:  # a new Gene
                geneFaDict[geneName] = ""
                LineNum = 0
                GeneSeq = ""
        elif n:
            LineNum += 1
            line = line.replace(" ", "")
            line = line.replace("\t", "")
            s = re.match("(\d+)([A-Z]+)", line)
            if s:  # like:61ATCGATCG
                seq = s.group(2)
                if LineNum == 2:  # gene seq ATG start
                    if seq[0:3] == "ATG":
                        GeneSeq += seq
                    else:
                        print geneName, "warning:(this start not ATG)", line
                        GeneSeq += seq
                elif LineNum > 2:  # other line seq
                    GeneSeq += seq
            else:
                print "warning line(no num):", line
        else:
            print "this line can't see!"
        line = f.readline()
    f.close()

    if BFlag == 1:
        print "get Gene Big Class!"
        geneFaDict1 = {}
        for g in geneFaDict:
            gene = g.split("-")[0]
            if gene not in geneFaDict1:
                geneFaDict1[gene] = geneFaDict[g]

        print len(geneFaDict), len(geneFaDict1)
        print "read file end!"
        return geneFaDict1

    print "read file end!"
    return geneFaDict


def BarListTypeDis(BarList1, BarList2, AllTypeList):
    AllTypeBarDisDict = {}
    for b in AllTypeList:
        AllTypeBarDisDict[b] = 0
    for b in AllTypeList:
        stri = "%s-SC" % (b)
        AllTypeBarDisDict[stri] = 0

    for b in BarList1:
        temp = b.split("_")
        bartype = temp[1]
        if bartype in AllTypeBarDisDict:
            AllTypeBarDisDict[bartype] += 1
        else:
            print "this barcode type error!", b

    for b in BarList2:
        temp = b.split("_")
        bartype = "%s-SC" % (temp[1])
        if bartype in AllTypeBarDisDict:
            AllTypeBarDisDict[bartype] += 1
        else:
            print "this barcode type error!", b

    return AllTypeBarDisDict


def FromBarcodeGetType(BarDict):
    AllTypeList = []
    for b in BarDict:
        temp = b.split("_")
        bartype = temp[1]
        if bartype not in AllTypeList:
            AllTypeList.append(bartype)

    return AllTypeList


def PoZheNameSort(NameList):
    numDict = {}
    numDict[-1] = []

    for i in NameList:
        m = re.match("(\w+)(-)(\d+)", i)
        if m:
            num = int(m.group(3))
            if num not in numDict:
                numDict[num] = []
                numDict[num].append(i)
            else:
                numDict[num].append(i)
        else:
            numDict[-1].append(i)

    sortList = []
    for i in sorted(numDict.keys(), reverse=False):
        for y in numDict[i]:
            if y not in sortList:
                sortList.append(y)
            else:
                print "repeat:", y
    return sortList


def ABBA(aDict):
    BAdict = {}
    for i in aDict:
        A = i
        B = aDict[i]
        if B not in BAdict:
            BAdict[B] = A
        else:
            print "repeat:", B
    return BAdict


def TCRSetNameToId(TCRSetName):
    ChainA = TCRSetName[0]
    ChainB = TCRSetName[1]

    stri = ""
    for i in ChainA:
        stri += i
        stri += "|"
    stri = stri.strip("|")
    stri += ";"
    for i in ChainB:
        stri += i
        stri += "|"
    stri = stri.strip("|")
    return stri


def copyNewDict(aDict):
    NewDict = {}
    for i in aDict:
        NewDict[i] = aDict[i]
    return NewDict


def getTCRXAXB(TCRSetName):
    if len(TCRSetName) == 2:
        AChain = TCRSetName[0]
        BChain = TCRSetName[1]
        stri = "%sA%sB" % (len(AChain), len(BChain))
        return stri
    else:
        print "TCR Set Name error:", TCRSetName
        return False


def ABChainKinds(TCRSetABList):
    ABChainListDict = {}
    for t in TCRSetABList:
        TCRASetList = t[0]
        TCRBSetList = t[1]

        for x in TCRASetList:
            for y in TCRBSetList:
                ABstri = "%s;%s" % (x, y)
                if ABstri not in ABChainListDict:
                    ABChainListDict[ABstri] = []
                    ABChainListDict[ABstri].append(t)
                else:
                    ABChainListDict[ABstri].append(t)

    return ABChainListDict


def ChainKinds(flag, TCRSetABList):
    ChainList = []
    ChainTCRSetABDict = {}
    for i in TCRSetABList:
        if flag == "A":
            temp = i[0]
        elif flag == "B":
            temp = i[1]

        for x in temp:
            if x not in ChainList:
                ChainList.append(x)
                ChainTCRSetABDict[x] = []
                ChainTCRSetABDict[x].append(i)
            else:
                ChainTCRSetABDict[x].append(i)
    return ChainTCRSetABDict


def jugOneChainInTCR(chainstri, TCRSetABList):
    FindTCRList = []
    for x in TCRSetABList:
        for y in x:
            if chainstri in y:
                FindTCRList.append(x)
    if len(FindTCRList) > 0:
        return FindTCRList
    else:
        return False


def getAB2KindsNum(SetNameList, flag):
    ChainSetList = []
    BianSetMapDict = {}  # {1:set(A1,A2)}
    BianNumDict = {}  # {1:2}
    BianSetNameListDict = {}  # {1:[set(A1,A2),set(B1)]}

    Bian = 1
    for i in SetNameList:
        if flag == 0:
            Chains = i[0]
        else:
            Chains = i[1]

        if Chains not in ChainSetList:
            ChainSetList.append(Chains)
            BianSetMapDict[Bian] = Chains
            BianNumDict[Bian] = 1
            BianSetNameListDict[Bian] = []
            BianSetNameListDict[Bian].append(i)
            Bian += 1
        else:
            BianHao = BInABFindA(BianSetMapDict, Chains)
            BianNumDict[BianHao] += 1
            BianSetNameListDict[BianHao].append(i)

    result = [BianSetMapDict, BianNumDict, BianSetNameListDict]
    return result


# base function end.


def BInABFindA(ABDict, Bstri):
    # input:set(A)
    # output:X
    # AB must be one one map

    FindA = ""
    for x in ABDict:
        if Bstri == ABDict[x]:
            FindA = x
            break
    if FindA != "":
        return FindA
    else:
        print "can't find AName:", Bstri
        return False


def getEleCombination(alist):
    CombList = []
    aLen = len(alist)
    for x in range(0, aLen - 1):
        for y in range(x + 1, aLen):
            temp = [alist[x], alist[y]]
            temp = set(temp)
            CombList.append(temp)

    return CombList


def fromTableGetMap2(table, keyCol, valueCol):
    # read head
    colDict = {}
    f = open(table)
    line = f.readline()
    line = line.strip("\n").split("\t")
    c = 0
    for i in line:
        if i not in colDict:
            colDict[i] = c
            c += 1
        else:
            print "warning:col name is repeat!", i
            f.close()
            return False
    f.close()

    # check
    if keyCol not in colDict:
        print "error:", keyCol
        return False
    if valueCol not in colDict:
        print "error:", colDict
        return False

    # get map
    mapDict = {}
    f = open(table)
    line = f.readline()
    line = f.readline()
    while line:
        temp = line.strip("\n").split("\t")
        key = temp[colDict[keyCol]]
        mapVal = temp[colDict[valueCol]]
        if key not in mapDict:
            mapDict[key] = mapVal
        elif str(mapDict[key]) != str(mapVal):
            print "WARNING:key has repeat!", key
        line = f.readline()
    f.close()
    return mapDict


def getBarTCRDataDict(BarTCRidDict, ChoFlag, BFlag):
    # {bar:{A:[],B:[]}}

    def listRemoveNULL(alist):
        blist = []
        for y in alist:
            if y != "":
                blist.append(y)
        return blist

    def selBigClu(name):
        sec = ""
        for i in name.split("-"):
            sec = i
            break
        return sec

    def getVCDR3Name(TCRchain, BFlag):
        temp = TCRchain.split(":")
        if len(temp) == 4 or len(temp) == 5:
            V = temp[0]
            CDR3 = temp[3]
            if BFlag == "T":
                V = selBigClu(V)
            stri = "%s:%s" % (V, CDR3)
        else:
            print "TCR name1 change to name2 error:", TCRchain
            stri = "-:-"
        return stri

    # main
    BarTCRChainDict1 = {}
    for i in BarTCRidDict:
        TCRid = BarTCRidDict[i]
        temp = TCRid.split(";")
        CA = temp[0].split("|")
        CB = temp[1].split("|")

        CA = listRemoveNULL(CA)
        CB = listRemoveNULL(CB)

        CA = set(CA)
        CB = set(CB)

        CANum = len(CA)
        CBNum = len(CB)
        CABNum = CANum + CBNum

        if ChoFlag == 1:
            if CANum in [1, 2] and CBNum in [1, 2] and CABNum >= 2:
                # print "get 1A1B,2A1B,1A2B,2A2B XCR!"
                BarTCRChainDict1[i] = {"A": CA, "B": CB}
        elif ChoFlag == 2:
            if CANum in [0, 1] and CBNum in [0, 1] and CABNum == 1:
                # print "get 0A1B,1A0B XCR!"
                BarTCRChainDict1[i] = {"A": CA, "B": CB}
    #
    BarTCRChainDict2 = {}
    for x in BarTCRChainDict1:  # barcode
        BarTCRChainDict2[x] = {}
        for y in BarTCRChainDict1[x]:  # A/B
            BarTCRChainDict2[x][y] = []
            for z in BarTCRChainDict1[x][y]:
                BarTCRChainDict2[x][y].append(getVCDR3Name(z, BFlag))
            BarTCRChainDict2[x][y] = set(BarTCRChainDict2[x][y])

    result = [BarTCRChainDict1, BarTCRChainDict2]
    return result


def TCRAna2(BarTCRChainDict2, BarTCRChainDictSC, BarTCRChainDictA, BarTCRChainDictSCA, XCRflag):
    def TCRNameListFindBian(TCRNameSet, TCRTNameMapDict):
        # input:[set(A),set(B)]
        # output:TCRT-X

        FindTCRT = ""
        for x in TCRTNameMapDict:
            if TCRNameSet == TCRTNameMapDict[x]:
                FindTCRT = x
                break
        if FindTCRT != "":
            return FindTCRT
        else:
            return False

    def TCRNameListFindBian2(TCRNameSetList, TCRTNameMapDict):
        # input:[set(A),set(B)]
        # output:TCRT-X

        FindTCRT = []
        for y in TCRNameSetList:
            for x in TCRTNameMapDict:
                if y == TCRTNameMapDict[x]:
                    FindTCRT.append(x)
                    break

        if len(FindTCRT) == len(TCRNameSetList):
            return FindTCRT
        else:
            print "have some TCRName not find!",
            return False

    def FromDictGetTCR(ANum, BNum, TCRTNameMapDict):
        # output:[TCR-X,]

        FinalTCRSetList = []
        for i in TCRTNameMapDict:
            ThisANum = len(TCRTNameMapDict[i][0])
            ThisBNum = len(TCRTNameMapDict[i][1])
            if ThisANum == ANum and ThisBNum == BNum:
                FinalTCRSetList.append(i)
        return FinalTCRSetList

    def TCRTListChaToTCRSet(TCRTNameMapDict, TCRTNameList):
        TCRSetNameList = []
        for i in TCRTNameList:
            if i in TCRTNameMapDict:
                TCRSetNameList.append(TCRTNameMapDict[i])
            else:
                print "can't get TCRT TCR Info:", i
                return False
        return TCRSetNameList

    # get TCRT Map Dict And TCRT Num Dict
    TCRTMapTCRTDict = {}  # {"TCRT-1":["TCRT-10"]}

    def TCRFirstName(BarXCRChainDict, XCRNameFlag):
        Bian = 1
        tc = 0
        bc = 0
        AllXCRList = []  # raw XCR list

        XCRTNumDict = {}  # XCRT-X:num
        XCRTNameMapDict = {}  # XCRT-X:[set(A),set(B)]
        XCRTBarListDict = {}  # XCRT-X:[b1,b2,...]
        BarXCRTDict = {}

        for i in BarXCRChainDict:
            bc += 1
            ThisXCR = [BarXCRChainDict[i]["A"], BarXCRChainDict[i]["B"]]
            if ThisXCR not in AllXCRList:
                if XCRNameFlag == 1:
                    Name = "%sT-%s" % (XCR, Bian)  # XCR temp number
                    BarXCRTDict[i] = Name
                    tc += 1
                elif XCRNameFlag == 2:
                    Name = "%sSC-%s" % (XCR, Bian)  # SC XCR temp number
                    BarXCRTDict[i] = Name
                else:
                    print "XCRNameFlag error!1 or 2!", XCRNameFlag
                    return False

                XCRTNumDict[Name] = 1
                Bian += 1
                XCRTNameMapDict[Name] = ThisXCR
                AllXCRList.append(ThisXCR)
                XCRTBarListDict[Name] = [i]
            else:
                FindXCRTBian = TCRNameListFindBian(ThisXCR, XCRTNameMapDict)  # find This XCR's bian
                if FindXCRTBian:
                    XCRTNumDict[FindXCRTBian] += 1
                    XCRTBarListDict[FindXCRTBian].append(i)
                    BarXCRTDict[i] = FindXCRTBian
                else:
                    print b, "find XCR's Bian error!", ThisXCR
                    return False

        if XCRNameFlag == 1:
            print "read TCR Raw Table barcode:", bc, "get Raw TCRT num:", tc, "XCRTNameMapDict:", len(
                XCRTNameMapDict), "XCRTNumDict:", len(XCRTNumDict), "XCRTBarListDict:", len(XCRTBarListDict)

        result = [XCRTNameMapDict, XCRTNumDict, XCRTBarListDict, BarXCRTDict]
        return result

    def TCRAB2MapAB2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict):
        # need function:FromDictGetTCR
        # AB2 map to A2B2,then AB2 try to denove new A2B2

        TCRT2A2BList = FromDictGetTCR(2, 2, TCRTNameMapDict)

        TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
        TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)
        TCRTAB2List = TCRT1A2BList + TCRT2A1BList

        TCRSetAB2List = TCRTListChaToTCRSet(TCRTNameMapDict, TCRTAB2List)
        TCRSet2A2BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT2A2BList)

        for i in TCRSetAB2List:  # for every 1A2B or 2A1B
            ThisTCRA = i[0]
            ThisTCRB = i[1]
            TCRTName1 = TCRNameListFindBian(i, TCRTNameMapDict)
            MapNum = 0
            MapList = []

            for x in TCRSet2A2BList:  # compare with all 2A2B TCR
                TCRA = x[0]
                TCRB = x[1]

                flag = 1
                for ta in ThisTCRA:
                    for tb in ThisTCRB:
                        if ta not in TCRA or tb not in TCRB:
                            flag = 0

                if flag == 1:
                    MapNum += 1
                    MapList.append(x)

            if MapNum == 1:
                # print i,MapNum
                TCRTName2 = TCRNameListFindBian(MapList[0], TCRTNameMapDict)
                # print TCRTName2,MapList[0]
                TCRTMapTCRTDict[TCRTName1] = TCRTName2
                # print "---------------"

        # map to 2A2B,and del raw,change TCR num
        for i in TCRTMapTCRTDict:
            MapToTCRT = TCRTMapTCRTDict[i]
            print "del:", i, "map to:", MapToTCRT
            print TCRTNumDict[i], TCRTNumDict[MapToTCRT]
            TCRTNameMapDict.pop(i)
            TCRTNumDict[MapToTCRT] += TCRTNumDict[i]
            print "after num:", TCRTNumDict[MapToTCRT]
            TCRTNumDict.pop(i)
            print "---------------"
        # map end.

        # try to denove 2A2B TCR
        # get new TCR info
        TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
        TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)

        TCRSet1A2BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT1A2BList)
        TCRSet2A1BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT2A1BList)
        AChainResult = getAB2KindsNum(TCRSet2A1BList, 0)
        A2BianSetMapDict = AChainResult[0]
        A2BianNumDict = AChainResult[1]
        A2BianSetNameListDict = AChainResult[2]

        BChainResult = getAB2KindsNum(TCRSet1A2BList, 1)
        B2BianSetMapDict = BChainResult[0]
        B2BianNumDict = BChainResult[1]
        B2BianSetNameListDict = BChainResult[2]

        # get amp A2 / B2
        A2AmpList = []
        B2AmpList = []
        for i in sorted(A2BianNumDict.items(), key=lambda x: x[1], reverse=True):
            Bian = i[0]
            Num = i[1]
            if Num >= 2:
                A2AmpList.append(Bian)
        for i in sorted(B2BianNumDict.items(), key=lambda x: x[1], reverse=True):
            Bian = i[0]
            Num = i[1]
            if Num >= 2:
                B2AmpList.append(Bian)

        # get A2 or B2 Amp(two TCR have) A/B chain List
        A2AmpBList = []
        A2AmpAList = []
        for x in A2AmpList:  # Chain's Bian
            ACom = []
            BCom = []  # this A2 amp's B Chain combination
            ThisTCRList = A2BianSetNameListDict[x]
            for y in ThisTCRList:
                AChain = y[0]
                BChain = y[1]
                for z in BChain:
                    BCom.append(z)
                for z in AChain:
                    ACom.append(z)
            BCom = set(BCom)
            ACom = set(ACom)
            A2AmpAList.append(ACom)
            A2AmpBList.append(BCom)

        B2AmpAList = []
        B2AmpBList = []
        for x in B2AmpList:
            ACom = []
            BCom = []
            ThisTCRList = B2BianSetNameListDict[x]
            for y in ThisTCRList:
                AChain = y[0]
                BChain = y[1]
                for z in AChain:
                    ACom.append(z)
                for z in BChain:
                    BCom.append(z)
            ACom = set(ACom)
            BCom = set(BCom)
            B2AmpAList.append(ACom)
            B2AmpBList.append(BCom)

        # print "A2AmpAList:",A2AmpAList
        # print "A2AmpBList:",A2AmpBList

        # print "B2AmpAList:",B2AmpAList
        # print "B2AmpBList:",B2AmpBList

        for c1 in range(0, len(A2AmpAList)):
            A2AmpA = A2AmpAList[c1]  # this A2 chain TCR set name
            A2AmpB = A2AmpBList[c1]  # this A2 chain TCR's B Chain List (a set)

            for c2 in range(0, len(B2AmpBList)):
                if A2AmpB == B2AmpBList[c2]:
                    if A2AmpA in B2AmpAList:
                        print "denove a new 2A2B TCR!", A2AmpA, A2AmpB

        # denove 2A2B end
        result = [TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict]
        return result

    # TCRAB2MapAB2 end.

    def TCRDenove(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, TCRTNameMapDictRaw, TCRTNumDictRaw):
        # denove new TCR
        # need function:TCRNameListFindBian,FromDictGetTCR

        DenoveBian = 1

        # denove 2A1B or 1A2B
        def denoveA1B1(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, flag, DenoveBian, TCRTNameMapDictRaw,
                       TCRTNumDictRaw):
            TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
            TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)
            TCRT1A1BList = FromDictGetTCR(1, 1, TCRTNameMapDict)

            TCRTMAMBList = TCRT1A2BList + TCRT2A1BList

            TCRSetAB1List = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT1A1BList)
            TCRSetAB2List = TCRTListChaToTCRSet(TCRTNameMapDict, TCRTMAMBList)

            if flag == "B":
                AllThisChainDict = ChainKinds("B", TCRSetAB1List)
            elif flag == "A":
                AllThisChainDict = ChainKinds("A", TCRSetAB1List)
            else:
                print "chain error:", flag
                return False

            for b in AllThisChainDict:
                TCRTempNum = len(AllThisChainDict[b])
                if TCRTempNum >= 2:  # this kind chain have more TCR
                    for x in range(0, TCRTempNum):
                        for y in range(x + 1, TCRTempNum):
                            N1TCR = AllThisChainDict[b][x]  # set name
                            N2TCR = AllThisChainDict[b][y]  # set name
                            if flag == "B":
                                N1 = list(N1TCR[0])[0]
                                N2 = list(N2TCR[0])[0]
                            elif flag == "A":
                                N1 = list(N1TCR[1])[0]
                                N2 = list(N2TCR[1])[0]

                            newXChain = set([N1, N2])
                            CChain = set([b])  # XChain's another chain
                            if flag == "B":
                                newTCR = [newXChain, CChain]
                            elif flag == "A":
                                newTCR = [CChain, newXChain]

                            N1TCRBian = TCRNameListFindBian(N1TCR, TCRTNameMapDict)
                            N2TCRBian = TCRNameListFindBian(N2TCR, TCRTNameMapDict)
                            if newTCR not in TCRSetAB2List and N1TCRBian and N2TCRBian:
                                N1TCRNum = TCRTNumDict[N1TCRBian]
                                N2TCRNum = TCRTNumDict[N2TCRBian]
                                TotalNum = N1TCRNum + N2TCRNum
                                N1TCRFrac = float(N1TCRNum) / float(TotalNum)
                                N2TCRFrac = float(N2TCRNum) / float(TotalNum)

                                if N1TCRNum >= 10 and N2TCRNum >= 10 and N1TCRFrac >= 0.2 and N2TCRFrac >= 0.2:
                                    DenoveName = "TCRD-%s" % (DenoveBian)
                                    TCRTNameMapDict[DenoveName] = newTCR
                                    TCRTMapTCRTDict[N1TCRBian] = DenoveName
                                    TCRTMapTCRTDict[N2TCRBian] = DenoveName
                                    TCRTNameMapDictRaw[DenoveName] = newTCR

                                    TCRTNameMapDict.pop(N1TCRBian)
                                    TCRTNameMapDict.pop(N2TCRBian)

                                    TCRTNumDict[DenoveName] = TCRTNumDict[N1TCRBian] + TCRTNumDict[N2TCRBian]
                                    TCRTNumDict.pop(N1TCRBian)
                                    TCRTNumDict.pop(N2TCRBian)
                                    TCRTNumDictRaw[DenoveName] = 0

                                    print "Denove 2A1B:", newTCR, DenoveName, N1TCRNum, N2TCRNum, TCRTNumDict[
                                        DenoveName]

                                    DenoveBian += 1
            print "after 1A2B/2A1B denove:", "TCRTNameMapDict:", len(TCRTNameMapDict), "TCRTNumDict:", len(
                TCRTNumDict), "TCRTMapTCRTDict:", len(TCRTMapTCRTDict), "TCRTNameMapDictRaw:", len(
                TCRTNameMapDictRaw), "TCRTNumDictRaw:", len(TCRTNumDictRaw)
            result = [TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, DenoveBian, TCRTNameMapDictRaw, TCRTNumDictRaw]
            return result

        # denove 1A1B end.

        # denove AB2
        def denoveAB2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, DenoveBian, TCRTNameMapDictRaw, TCRTNumDictRaw):

            TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
            TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)

            TCRSet1A2BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT1A2BList)
            TCRSet2A1BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT2A1BList)
            AChainResult = getAB2KindsNum(TCRSet2A1BList, 0)
            A2BianSetMapDict = AChainResult[0]
            A2BianNumDict = AChainResult[1]
            A2BianSetNameListDict = AChainResult[2]  # bian:[set(A1,A2)

            BChainResult = getAB2KindsNum(TCRSet1A2BList, 1)
            B2BianSetMapDict = BChainResult[0]
            B2BianNumDict = BChainResult[1]
            B2BianSetNameListDict = BChainResult[2]

            # get amp A2 / B2
            A2AmpList = []  # bian
            B2AmpList = []  # bian
            for i in sorted(A2BianNumDict.items(), key=lambda x: x[1], reverse=True):
                Bian = i[0]
                Num = i[1]
                if Num >= 2:
                    A2AmpList.append(Bian)
            for i in sorted(B2BianNumDict.items(), key=lambda x: x[1], reverse=True):
                Bian = i[0]
                Num = i[1]
                if Num >= 2:
                    B2AmpList.append(Bian)

            # get A2 or B2 Amp(two TCR have) A/B chain List
            A2AmpBList = []
            A2AmpAList = []
            for x in A2AmpList:  # bian
                ACom = []
                BCom = []  # this A2 amp's B Chain combination
                ThisTCRList = A2BianSetNameListDict[x]  # this A2's TCR set name's list
                for y in ThisTCRList:
                    AChain = y[0]
                    BChain = y[1]
                    for z in BChain:
                        BCom.append(z)
                    for z in AChain:
                        ACom.append(z)
                BCom = set(BCom)
                ACom = set(ACom)
                A2AmpAList.append(ACom)  # TCR set name
                A2AmpBList.append(BCom)  # TCR set name

            B2AmpAList = []  # [set(A1,A2,A3),set(A4,A5)]
            B2AmpBList = []  # [set(B1,B2),set(B3,B4)]
            for x in B2AmpList:
                ACom = []
                BCom = []
                ThisTCRList = B2BianSetNameListDict[x]  # this B2's TCR set name
                for y in ThisTCRList:
                    AChain = y[0]
                    BChain = y[1]
                    for z in AChain:
                        ACom.append(z)
                    for z in BChain:
                        BCom.append(z)
                ACom = set(ACom)
                BCom = set(BCom)
                B2AmpAList.append(ACom)
                B2AmpBList.append(BCom)

            # for every A2 chain kind
            for c1 in range(0, len(A2AmpAList)):
                A2AmpA = A2AmpAList[c1]  # this A2 chain TCR Set Name
                A2AmpB = list(A2AmpBList[c1])  # this A2 chain TCR's B Chain TCRSet Name List (a set)

                # get this A2 chain's B2 chain combination
                for x in range(0, len(A2AmpB)):
                    for y in range(x + 1, len(A2AmpB)):
                        B2Com = set([A2AmpB[x], A2AmpB[y]])

                        if B2Com in B2AmpBList:  # this B2Com in B2Amp List
                            for c2 in range(0, len(B2AmpBList)):  # which pos
                                if B2AmpBList[c2] == B2Com:
                                    ThisB2AmpAList = B2AmpAList[c2]  # get this kind B2Com's A chain List

                                    AFlag = 1
                                    for z in A2AmpA:
                                        if z not in ThisB2AmpAList:
                                            AFlag = 0

                                    if AFlag == 1:
                                        # print "AB2 denove a new 2A2B TCR!",A2AmpA,A2AmpB
                                        newTCR = [A2AmpA, B2Com]
                                        DenoveName = "TCRD-%s" % (DenoveBian)
                                        print "AB2 denove a new 2A2B TCR!", newTCR, DenoveName
                                        TCRTNameMapDict[DenoveName] = newTCR
                                        TCRTNameMapDictRaw[DenoveName] = newTCR
                                        TCRTNumDictRaw[DenoveName] = 0
                                        TCRTNumDict[DenoveName] = 0

                                        DenoveBian += 1

                                        for c in list(A2AmpA):  # this A2 chain TCR Set Name
                                            N1TCRSetName = [set([c]), B2Com]
                                            N1TCRBian = TCRNameListFindBian(N1TCRSetName, TCRTNameMapDict)

                                            TCRTMapTCRTDict[N1TCRBian] = DenoveName
                                            TCRTNameMapDict.pop(N1TCRBian)
                                            TCRTNumDict[DenoveName] += TCRTNumDict[N1TCRBian]
                                            TCRTNumDict.pop(N1TCRBian)

                                        for c in B2Com:
                                            N1TCRSetName = [A2AmpA, set([c])]
                                            N1TCRBian = TCRNameListFindBian(N1TCRSetName, TCRTNameMapDict)
                                            TCRTMapTCRTDict[N1TCRBian] = DenoveName
                                            TCRTNameMapDict.pop(N1TCRBian)
                                            TCRTNumDict[DenoveName] += TCRTNumDict[N1TCRBian]
                                            TCRTNumDict.pop(N1TCRBian)
                        # else:
                        #    print "B2Com not in B2AmpBList:",B2Com,B2AmpBList
            print "after 1A2B/2A1B denove:", "TCRTNameMapDict:", len(TCRTNameMapDict), "TCRTNumDict:", len(
                TCRTNumDict), "TCRTMapTCRTDict:", len(TCRTMapTCRTDict), "TCRTNameMapDictRaw:", len(
                TCRTNameMapDictRaw), "TCRTNumDictRaw:", len(TCRTNumDictRaw)
            result = [TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, DenoveBian, TCRTNameMapDictRaw, TCRTNumDictRaw]
            return result

        # denove 2A2B end

        # denove main
        DenResult = denoveA1B1(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, "B", DenoveBian, TCRTNameMapDictRaw,
                               TCRTNumDictRaw)
        TCRTNameMapDict = DenResult[0]
        TCRTNumDict = DenResult[1]
        TCRTMapTCRTDict = DenResult[2]
        DenoveBian = DenResult[3]
        TCRTNameMapDictRaw = DenResult[4]
        TCRTNumDictRaw = DenResult[5]
        print "2A1B finish!"

        DenResult = denoveA1B1(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, "A", DenoveBian, TCRTNameMapDictRaw,
                               TCRTNumDictRaw)
        TCRTNameMapDict = DenResult[0]
        TCRTNumDict = DenResult[1]
        TCRTMapTCRTDict = DenResult[2]
        DenoveBian = DenResult[3]
        TCRTNameMapDictRaw = DenResult[4]
        TCRTNumDictRaw = DenResult[5]
        print "1A2B finish!"

        DenResult = denoveAB2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, DenoveBian, TCRTNameMapDictRaw,
                              TCRTNumDictRaw)
        TCRTNameMapDict = DenResult[0]
        TCRTNumDict = DenResult[1]
        TCRTMapTCRTDict = DenResult[2]
        DenoveBian = DenResult[3]
        TCRTNameMapDictRaw = DenResult[4]
        TCRTNumDictRaw = DenResult[5]

        result = [TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, TCRTNameMapDictRaw, TCRTNumDictRaw]
        return result
        # denove main end

    # TCRDenove function end.

    def TCRMerge(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict):
        # TCR 1A1B merge to 1A2B/2A1B/2A2B
        # A1B1 first merge to 1A2B/2A1B,then merge to 2A2B

        # need function:TCRNameListFindBian,FromDictGetTCR

        # change to TCR Set Name
        def AOrB2CommChain(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict):
            TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
            TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)

            TCRTAOrB2List = TCRT1A2BList + TCRT2A1BList
            TCRSetAOrB2List = TCRTListChaToTCRSet(TCRTNameMapDict, TCRTAOrB2List)

            b = ABChainKinds(TCRSetAOrB2List)
            print "have common chain:"
            for i in b:
                if len(b[i]) >= 2:
                    print i
                    HaveTCRBianList = TCRNameListFindBian2(b[i], TCRTNameMapDict)
                    for z in HaveTCRBianList:
                        print z, TCRTNumDict[z], TCRTNameMapDict[z]
                    print "-------------"

        def ABMergeToAOrB2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict):

            # first,get data
            TCRT1A1BList = FromDictGetTCR(1, 1, TCRTNameMapDict)
            TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
            TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)

            TCRTAOrB2List = TCRT1A2BList + TCRT2A1BList
            TCRSetAOrB2List = TCRTListChaToTCRSet(TCRTNameMapDict, TCRTAOrB2List)
            TCRSet1A1BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT1A1BList)

            TCRT2AOrBBeMapDict = {}
            TCRT1A1BMapListDict = {}
            for i in TCRTAOrB2List:
                TCRSetA = TCRTNameMapDict[i][0]
                TCRSetB = TCRTNameMapDict[i][1]

                MapSetNameList = []
                for x in TCRSet1A1BList:
                    tempTCRSetA = x[0]
                    tempTCRSetB = x[1]

                    if list(tempTCRSetA)[0] in TCRSetA and list(tempTCRSetB)[0] in TCRSetB:
                        tempTCRT1A1B = TCRNameListFindBian(x, TCRTNameMapDict)
                        if tempTCRT1A1B not in TCRT1A1BMapListDict:
                            TCRT1A1BMapListDict[tempTCRT1A1B] = []
                            TCRT1A1BMapListDict[tempTCRT1A1B].append(i)
                        else:
                            TCRT1A1BMapListDict[tempTCRT1A1B].append(i)

                        MapSetNameList.append(x)

                if len(MapSetNameList) > 0:
                    TCRT2AOrBBeMapDict[i] = MapSetNameList

            # get data end.

            # 1A1B TCR be merged to two and more kinds of TCR
            for i in TCRT1A1BMapListDict:
                if len(TCRT1A1BMapListDict[i]) >= 2:
                    setname = TCRTNameMapDict[i]
                    # print "this TCR:",i,TCRTNameMapDict[i],TCRTNumDict[i],TCRT1A1BMapListDict[i]
                    ChoTCR = ""
                    ChoTCRNum = 0
                    for y in TCRT1A1BMapListDict[i]:
                        if TCRTNumDict[y] >= ChoTCRNum:
                            ChoTCR = y
                            ChoTCRNum = TCRTNumDict[y]
                        # print "be merged TCR:",y,TCRTNameMapDict[y],TCRTNumDict[y]
                    # print "Choose:",ChoTCR,ChoTCRNum
                    for y in TCRT1A1BMapListDict[i]:
                        if y != ChoTCR:
                            TCRT2AOrBBeMapDict[y].remove(setname)
                            # if len(TCRT2AOrBBeMapDict[y]) > 0:
                            #    print "aaaa:",TCRT2AOrBBeMapDict[y]
                    # every 1A1B TCR only be merged to one 1A2B or 2A1B TCR
                    TCRT1A1BMapListDict[i] = [ChoTCR]

            # check
            # check end.

            # choose TCR end.

            # 1A1B merged to 1A2B or 2A1B
            for i in TCRT2AOrBBeMapDict:
                judNumDict = {i: TCRTNumDict[i]}
                TotalNum = TCRTNumDict[i]
                templist = TCRT2AOrBBeMapDict[i]
                for x in templist:
                    tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                    judNumDict[tempBian] = TCRTNumDict[tempBian]
                    TotalNum += TCRTNumDict[tempBian]

                judfracDict = {}
                for y in judNumDict:
                    judfracDict[y] = (float(judNumDict[y]) / TotalNum)

                if len(judNumDict) == 2:  # This 2A1B or 1A2B TCR only be one 1A1B TCR merged,and this 1A1B be mapped to only 1 2A1B/1A2B!

                    ChoTCR = i  # image
                    ChoTCRNum = judNumDict[i]

                    uniflag = 1
                    judNumDict.pop(i)  # check
                    for x in judNumDict:
                        if len(TCRT1A1BMapListDict[x]) != 1:
                            uniflag = 0

                    if uniflag == 1:
                        # print "s1:",i,TCRTNameMapDict[i],TCRTNumDict[i]
                        This1A1BNum = 0
                        This1A1BTCR = ""
                        for y in judNumDict:  # TCRT Name
                            # print "1A1B:",y,judNumDict[y]
                            This1A1BNum = judNumDict[y]
                            This1A1BTCR = y

                            if float(ChoTCRNum / This1A1BNum) >= 0.2 and ChoTCRNum > 2:
                                # print "really!"
                                TCRTMapTCRTDict[This1A1BTCR] = i
                                TCRTNumDict[i] += TCRTNumDict[This1A1BTCR]
                                TCRTNameMapDict.pop(This1A1BTCR)
                                TCRTNumDict.pop(This1A1BTCR)

                            elif This1A1BNum == 1 and ChoTCRNum == 1:
                                # print "unknown"
                                TCRTMapTCRTDict[This1A1BTCR] = i
                                TCRTNumDict[i] += TCRTNumDict[This1A1BTCR]
                                TCRTNameMapDict.pop(This1A1BTCR)
                                TCRTNumDict.pop(This1A1BTCR)
                            else:
                                # print "doublet!"
                                TCRTMapTCRTDict[i] = This1A1BTCR
                                TCRTNumDict[This1A1BTCR] += TCRTNumDict[i]
                                TCRTNameMapDict.pop(i)
                                TCRTNumDict.pop(i)
                        # print "----------------"

                elif len(
                        judNumDict) == 3:  # This 2A1B or 1A2B TCR be two kinds of 1A1B TCR merged,and this 1A1B be mapped to only 1 2A1B/1A2B!

                    ChoTCR = i
                    ChoTCRNum = judNumDict[i]
                    TotalNum = ChoTCRNum

                    # check
                    uniflag = 1
                    judNumDict.pop(i)
                    for x in judNumDict:
                        if len(TCRT1A1BMapListDict[x]) != 1:
                            uniflag = 0
                    # check end.

                    if uniflag == 1:
                        # print "s2:",i,TCRTNameMapDict[i],TCRTNumDict[i]
                        # get total num
                        for y in judNumDict:
                            # print "1A1B:",y,judNumDict[y],TCRTNameMapDict[y]
                            TotalNum += judNumDict[y]

                        ChoFrac = float(ChoTCRNum) / float(TotalNum)
                        if ChoTCRNum >= 2 and ChoFrac >= 0.2:
                            # print "really:",ChoTCR,ChoFrac
                            for y in judNumDict:
                                TCRTMapTCRTDict[y] = ChoTCR
                                TCRTNumDict[ChoTCR] += TCRTNumDict[y]
                                TCRTNameMapDict.pop(y)
                                TCRTNumDict.pop(y)

                        else:  # choose one most 1A1B,This 1A2B/2A1B be merged to this 1A1B TCR
                            ChoTCRMergeTo = ""
                            for y in judNumDict:
                                if judNumDict[y] >= ChoTCRNum:
                                    ChoTCRMergeTo = y
                            # print "doublet!merged to:",ChoTCRMergeTo

                            TCRTMapTCRTDict[ChoTCR] = ChoTCRMergeTo
                            TCRTNumDict[ChoTCRMergeTo] += TCRTNumDict[ChoTCR]
                            TCRTNameMapDict.pop(ChoTCR)
                            TCRTNumDict.pop(ChoTCR)

                        # print "---------------------"
                elif len(judNumDict) >= 4:
                    print "this 2A1B 1A2B have error 1A1B num!", judNumDict

            # 1A1B merged to 1A2B or 2A1B end.
            print "after 1A1B merged to 1A2B/2A1B:", "TCRTNameMapDict:", len(TCRTNameMapDict), "TCRTNumDict:", len(
                TCRTNumDict), "TCRTMapTCRTDict:", len(TCRTMapTCRTDict)
            result = [TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict]
            return result

        def AOrB2MergeToA2B2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict):
            # A2B1 A1B2 merge to A2B2
            TCRT2A2BList = FromDictGetTCR(2, 2, TCRTNameMapDict)
            TCRT1A2BList = FromDictGetTCR(1, 2, TCRTNameMapDict)
            TCRT2A1BList = FromDictGetTCR(2, 1, TCRTNameMapDict)

            TCRTAOrB2List = TCRT1A2BList + TCRT2A1BList

            TCRSet2A2BList = TCRTListChaToTCRSet(TCRTNameMapDict, TCRT2A2BList)
            TCRSetAOrB2List = TCRTListChaToTCRSet(TCRTNameMapDict, TCRTAOrB2List)

            TCRT2A2BList = TCRNameListFindBian2(TCRSet2A2BList, TCRTNameMapDict)

            TCRT2A2BBeMapDict = {}
            TCRA2OrB2MapTo2A2BDict = {}

            for i in TCRT2A2BList:
                TCRSetA = TCRTNameMapDict[i][0]
                TCRSetB = TCRTNameMapDict[i][1]

                MapList = []
                for x in TCRSetAOrB2List:  # consider all 1A2B or 2A1B
                    tempTCRSetA = x[0]
                    tempTCRSetB = x[1]
                    This2AOr2BName = TCRNameListFindBian(x, TCRTNameMapDict)

                    TCRType = "%sA%sB" % (len(tempTCRSetA), len(tempTCRSetB))
                    if TCRType == "1A2B":
                        if list(tempTCRSetA)[0] in TCRSetA and tempTCRSetB == TCRSetB:
                            MapList.append(x)
                            if This2AOr2BName not in TCRA2OrB2MapTo2A2BDict:
                                TCRA2OrB2MapTo2A2BDict[This2AOr2BName] = []
                                TCRA2OrB2MapTo2A2BDict[This2AOr2BName].append(i)
                            else:
                                # print "add more 2A2B:",i,TCRTNameMapDict[i]
                                TCRA2OrB2MapTo2A2BDict[This2AOr2BName].append(i)
                    elif TCRType == "2A1B":
                        if tempTCRSetA == TCRSetA and list(tempTCRSetB)[0] in TCRSetB:
                            MapList.append(x)
                            if This2AOr2BName not in TCRA2OrB2MapTo2A2BDict:
                                TCRA2OrB2MapTo2A2BDict[This2AOr2BName] = []
                                TCRA2OrB2MapTo2A2BDict[This2AOr2BName].append(i)
                            else:
                                # print "add more 2A2B:",i,TCRTNameMapDict[i]
                                TCRA2OrB2MapTo2A2BDict[This2AOr2BName].append(i)
                    else:
                        print "TCR Type error:", x

                if len(MapList) > 0:
                    TCRT2A2BBeMapDict[i] = MapList

            # consider 1A2A or 2A1B maped to two and more 2A2B
            # print "1A2A or 2A1B maped to two 2A2B:"
            for i in TCRA2OrB2MapTo2A2BDict:
                if len(TCRA2OrB2MapTo2A2BDict[i]) >= 2:
                    # print "1A2B or 2A1B:",i,TCRTNameMapDict[i],TCRTNumDict[i]
                    Cho2A2BTCR = ""
                    Cho2A2BTCRNum = 0
                    for x in TCRA2OrB2MapTo2A2BDict[i]:  # 2A2B is Bian Name
                        if TCRTNumDict[x] >= Cho2A2BTCRNum:
                            Cho2A2BTCR = x
                            Cho2A2BTCRNum = TCRTNumDict[x]
                            # print x,TCRTNameMapDict[x],TCRTNumDict[x]
                    # print "Choose 2A2B TCR:",Cho2A2BTCR
                    This2AOr2BSetName = TCRTNameMapDict[i]
                    for x in TCRA2OrB2MapTo2A2BDict[i]:
                        if x != Cho2A2BTCR:
                            # print "before remove:",TCRT2A2BBeMapDict[x]
                            TCRT2A2BBeMapDict[x].remove(This2AOr2BSetName)
                            # print "remove This2AOr2BSetName in:",x,TCRT2A2BBeMapDict[x]
                            if len(TCRT2A2BBeMapDict[x]) == 0:
                                TCRT2A2BBeMapDict.pop(x)
                                # print "remove this 2A2B in TCRT2A2BBeMapDict!",x

            # consider 1A2A or 2A1B maped to two and more 2A2B end.

            # every 2A2B's merged 1A2B/2A1B TCR
            MergeInfo = ""
            for i in TCRT2A2BBeMapDict:
                This2A2BKinds = len(TCRT2A2BBeMapDict[i])

                stri = "This 2A2B:%s,SetName:%s,RawNum:%s,MergedTCR:%s," % (
                i, TCRTNameMapDict[i], TCRTNumDict[i], TCRT2A2BBeMapDict[i])
                MergeInfo += stri
                # print stri

                if This2A2BKinds == 4 or This2A2BKinds == 3:
                    stri = "MergeINFO:"
                    for x in TCRT2A2BBeMapDict[i]:  # BeMap is TCR Set Name,2A2B is Bian Name
                        tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                        TCRTMapTCRTDict[tempBian] = i
                        TCRTNumDict[i] += TCRTNumDict[tempBian]

                        TCRTNameMapDict.pop(tempBian)
                        TCRTNumDict.pop(tempBian)

                elif This2A2BKinds == 2:
                    TotalNum = TCRTNumDict[i]
                    ChoTCR = i
                    ChoTCRNum = TCRTNumDict[i]
                    for x in TCRT2A2BBeMapDict[i]:  # BeMap is TCR Set Name,2A2B is Bian Name
                        tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                        TotalNum += TCRTNumDict[tempBian]

                    if float(TCRTNumDict[i]) / float(TotalNum) >= 0.1:  # these two 1A2B 2A1B merged to 2A2B
                        for x in TCRT2A2BBeMapDict[i]:
                            tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                            TCRTMapTCRTDict[tempBian] = i
                            TCRTNumDict[i] += TCRTNumDict[tempBian]

                            TCRTNameMapDict.pop(tempBian)
                            TCRTNumDict.pop(tempBian)
                    else:
                        theseTCRT = [i]
                        for x in TCRT2A2BBeMapDict[i]:
                            tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                            theseTCRT.append(tempBian)
                            if TCRTNumDict[tempBian] >= ChoTCRNum:
                                ChoTCR = tempBian
                                ChoTCRNum = TCRTNumDict[tempBian]
                        for x in theseTCRT:
                            if x != ChoTCR:
                                TCRTMapTCRTDict[x] = ChoTCR
                                TCRTNumDict[ChoTCR] += TCRTNumDict[x]

                                TCRTNameMapDict.pop(x)
                                TCRTNumDict.pop(x)

                elif This2A2BKinds == 1:
                    TotalNum = TCRTNumDict[i]
                    ChoTCR = i
                    ChoTCRNum = TCRTNumDict[i]
                    for x in TCRT2A2BBeMapDict[i]:  # BeMap is TCR Set Name,2A2B is Bian Name
                        tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                        TotalNum += TCRTNumDict[tempBian]

                    if float(TCRTNumDict[i]) / float(TotalNum) >= 0.1:  # this 1A2B/2A1B merged to 2A2B
                        for x in TCRT2A2BBeMapDict[i]:
                            tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                            TCRTMapTCRTDict[tempBian] = i
                            TCRTNumDict[i] += TCRTNumDict[tempBian]

                            TCRTNameMapDict.pop(tempBian)
                            TCRTNumDict.pop(tempBian)
                    else:
                        theseTCRT = [i]
                        for x in TCRT2A2BBeMapDict[i]:
                            tempBian = TCRNameListFindBian(x, TCRTNameMapDict)
                            theseTCRT.append(tempBian)
                            if TCRTNumDict[tempBian] >= ChoTCRNum:
                                ChoTCR = tempBian
                                ChoTCRNum = TCRTNumDict[tempBian]
                        for x in theseTCRT:
                            if x != ChoTCR:
                                TCRTMapTCRTDict[x] = ChoTCR
                                TCRTNumDict[ChoTCR] += TCRTNumDict[x]

                                TCRTNameMapDict.pop(x)
                                TCRTNumDict.pop(x)


                else:
                    print "error:2A2B TCR has more than 4 kinds of TCR merged!", i, This2A2BKinds
                # print "-------------------"

            print "after 1A2B/2A1B merge to 2A2B:", "TCRTNameMapDict:", len(TCRTNameMapDict), "TCRTNumDict:", len(
                TCRTNumDict), "TCRTMapTCRTDict:", len(TCRTMapTCRTDict)

            result = [TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict]
            return result
            # every 2A2B's merged 1A2B/2A1B TCR end.

        def ReNameTCR(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict):

            if TCRTNameMapDict.keys() == TCRTNumDict.keys():
                TCRTMapTCRFDict = {}  # TCRT-X TCR-X
                TCRTBeMapTCRTList = {}  # final TCRT-X have how many TCRT-X
                TCRTMapTCRFDict = {}
                TCRTBelongTCRTDict = {}  # a seq TCRT finally belong to which TCRT?
                c = 0

                # rename TCR
                c = 1
                for i in sorted(TCRTNumDict.items(), key=lambda x: x[1], reverse=True):
                    TCRTName = i[0]
                    TCRNum = i[1]
                    TCRFName = "%s-%s" % (XCR, c)
                    TCRTMapTCRFDict[TCRTName] = TCRFName
                    c += 1
                # rename TCR end.

                # TCRT merge to TCRT.a -> b,b -> c,then a -> c. a be merged to c
                for i in TCRTMapTCRTDict:
                    flag = 1
                    MapTCRT = TCRTMapTCRTDict[i]
                    TCRTList = [i]
                    while flag == 1:
                        if MapTCRT in TCRTMapTCRTDict:  # hasn't merged end.
                            TCRTList.append(MapTCRT)
                            MapTCRT = TCRTMapTCRTDict[MapTCRT]
                        else:  # merged end.
                            TCRTList.append(MapTCRT)
                            flag = 0

                    # add TCRT belong info
                    for x in TCRTList:
                        if x not in TCRTBelongTCRTDict:
                            TCRTBelongTCRTDict[x] = MapTCRT
                            c += 1
                        elif TCRTBelongTCRTDict[x] != MapTCRT:
                            print "warning:this TCRT exist (TCRTBelongTCRTDict)!", x, "raw:", TCRTBelongTCRTDict[
                                x], "now:", MapTCRT

                    # a final TCRT have many merged path way
                    if MapTCRT not in TCRTBeMapTCRTList:
                        TCRTBeMapTCRTList[MapTCRT] = TCRTList
                    else:
                        TCRTBeMapTCRTList[MapTCRT] = TCRTBeMapTCRTList[MapTCRT] + TCRTList

                # add some TCR no have other TCR merge
                for i in TCRTNumDict:
                    if i not in TCRTBeMapTCRTList:
                        TCRTBeMapTCRTList[i] = [i]
                        TCRTBelongTCRTDict[i] = i
                        c += 1

                # TCRT ~ TCR Dict
                for x in TCRTBeMapTCRTList:
                    TCRFName = TCRTMapTCRFDict[x]
                    for y in TCRTBeMapTCRTList[x]:
                        if y not in TCRTMapTCRFDict:
                            TCRTMapTCRFDict[y] = TCRFName

                # check
                TCRTNumDictTotalNum = 0
                for t in TCRTNumDict:
                    TCRTNumDictTotalNum += TCRTNumDict[t]

                print "ReName function check:TCRTNumDict TotalBarNum:", TCRTNumDictTotalNum, "TCRTBelongTCRTDict(should == raw TCRT num):", len(
                    TCRTBelongTCRTDict)
                # TCRT merge to TCRT end.

                result = [TCRTBeMapTCRTList, TCRTMapTCRFDict, TCRTBelongTCRTDict]
                return result

        # ReNameTCR end.

        # merge main
        # AOrB2CommChain(TCRTNameMapDict,TCRTNumDict,TCRTMapTCRTDict)

        # 1A1B Merge to 1A2B/2A1B
        result = ABMergeToAOrB2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict)
        TCRTNameMapDict = result[0]
        TCRTNumDict = result[1]
        TCRTMapTCRTDict = result[2]

        # 1A2B/2A1B merge to 2A2B
        result = AOrB2MergeToA2B2(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict)
        TCRTNameMapDict = result[0]
        TCRTNumDict = result[1]
        TCRTMapTCRTDict = result[2]

        # TCR rename
        ReNameTCRResult = ReNameTCR(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict)
        TCRTBeMapTCRTList = ReNameTCRResult[0]
        TCRTMapTCRFDict = ReNameTCRResult[1]
        TCRTBelongTCRTDict = ReNameTCRResult[2]

        result = [TCRTBeMapTCRTList, TCRTNumDict, TCRTMapTCRFDict, TCRTBelongTCRTDict]
        return result

        # merge main end.

    def SCMapToTCR(SCTCRTNameMapDict, SCTCRTNumDict, TCRTNameMapDictRaw, TCRTNumDict):

        TCRTBeSCMapListDict = {}  # {TCRT:[SCTCR1,SCTCR2]}
        SCTCRMapListDict = {}  # {SCTCR:[TCRT-1,TCRT-2]}
        SCTCRBelongTCRTDict = {}

        # every final TCRT,how many SC TCRT map to myself?A SCTCRT can mat to how many TCRT?
        for t in TCRTNumDict:
            TCRTSetName = TCRTNameMapDictRaw[t]
            TCRTCA = TCRTSetName[0]
            TCRTCB = TCRTSetName[1]
            mapList = []
            # find all SC TCR
            for s in SCTCRTNameMapDict:
                SCCA = SCTCRTNameMapDict[s][0]
                SCCB = SCTCRTNameMapDict[s][1]

                mapsucflag = 0
                if (len(SCCA)) > 0:
                    for x in SCCA:
                        if x in TCRTCA:
                            mapsucflag = 1
                elif (len(SCCB)) > 0:
                    for x in SCCB:
                        if x in TCRTCB:
                            mapsucflag = 1

                if mapsucflag == 1:
                    mapList.append(s)
                    if s not in SCTCRMapListDict:
                        SCTCRMapListDict[s] = []
                        SCTCRMapListDict[s].append(t)
                    else:
                        SCTCRMapListDict[s].append(t)

            if len(mapList) > 0:
                TCRTBeSCMapListDict[t] = mapList
        print "TCRTBeSCMapListDict:", len(TCRTBeSCMapListDict)

        # if a SC TCR map to two more TCRT,remove! and update TCRTBeSCMapListDict,SCTCRMapListDict
        SCTCRMapMoreTCRTList = []
        for y in SCTCRMapListDict:
            if len(SCTCRMapListDict[y]) >= 2:
                SCTCRMapMoreTCRTList.append(y)
        for y in SCTCRMapMoreTCRTList:
            SCTCRMapListDict.pop(y)

        for x in TCRTBeSCMapListDict:
            SCMapList = TCRTBeSCMapListDict[x]
            tempRemoveSCTCR = []
            for y in SCMapList:
                if y in SCTCRMapMoreTCRTList:
                    tempRemoveSCTCR.append(y)
            for y in tempRemoveSCTCR:
                TCRTBeSCMapListDict[x].remove(y)

        removeTCRTList = []
        for x in TCRTBeSCMapListDict:
            if len(TCRTBeSCMapListDict[x]) == 0:
                removeTCRTList.append(x)

        for x in removeTCRTList:
            TCRTBeSCMapListDict.pop(x)
        # remove end.

        for x in TCRTBeSCMapListDict:
            for y in TCRTBeSCMapListDict[x]:
                if y not in SCTCRBelongTCRTDict:
                    SCTCRBelongTCRTDict[y] = x
                else:
                    print "warning:SC TCR has exists in SCTCRBelongTCRTDict!", y, SCTCRBelongTCRTDict[y], x

        result = [TCRTBeSCMapListDict, SCTCRBelongTCRTDict]
        return result

    # SCMapToTCR end.
    def BarBelongFinal(XCRTBarListDict, XCRTBelongXCRTDict):
        XCRTBarListDict2 = {}
        Alist = XCRTBarListDict.keys()
        Blist = XCRTBelongXCRTDict.keys()

        for t in XCRTBelongXCRTDict:
            BelongXCR = XCRTBelongXCRTDict[t]
            if t in XCRTBarListDict:
                ThisXCRBarList = XCRTBarListDict[t]
            else:
                ThisXCRBarList = []

            if BelongXCR not in XCRTBarListDict2:
                XCRTBarListDict2[BelongXCR] = ThisXCRBarList
            else:
                XCRTBarListDict2[BelongXCR] += ThisXCRBarList
        # check
        RawAllBar = []
        for b in XCRTBarListDict:
            RawAllBar += XCRTBarListDict[b]
        NowAllBar = []
        for b in XCRTBarListDict2:
            NowAllBar += XCRTBarListDict2[b]

        RawAllBar = set(RawAllBar)
        NowAllBar = set(NowAllBar)

        print "BarBelongFinal function check:", "XCRTBelongXCRTDict(should == now exists XCR):", len(
            XCRTBelongXCRTDict), "XCRTBarListDict(should == all raw XCR num):", len(
            XCRTBarListDict), "XCRTBarListDict's barcode num(should == total barcode num):", len(
            RawAllBar), "XCRTBarListDict2's XCR num:", len(XCRTBarListDict2), "XCRTBarListDict2's barcode num:", len(
            NowAllBar)

        return XCRTBarListDict2

    def GetTCRStat(TCRTBeMapTCRTList, TCRTNameMapDictRaw):
        TCRTStatDict = {}
        for t in TCRTBeMapTCRTList:
            FinalTCRTSetName = TCRTNameMapDictRaw[t]
            FinalTCRTChainStat = getTCRXAXB(FinalTCRTSetName)

            if FinalTCRTChainStat == "1A1B":
                for x in TCRTBeMapTCRTList[t]:
                    ThisTCRTSetName = TCRTNameMapDictRaw[x]
                    ThisTCRTChainStat = getTCRXAXB(ThisTCRTSetName)

                    if ThisTCRTChainStat != "1A1B":
                        TCRTStatDict[x] = "doublet"
                    else:
                        TCRTStatDict[x] = "-"
            elif FinalTCRTChainStat == "1A2B" or FinalTCRTChainStat == "2A1B":
                for x in TCRTBeMapTCRTList[t]:
                    ThisTCRTSetName = TCRTNameMapDictRaw[x]
                    ThisTCRTChainStat = getTCRXAXB(ThisTCRTSetName)

                    if ThisTCRTChainStat == FinalTCRTChainStat and ThisTCRTSetName == FinalTCRTSetName:
                        TCRTStatDict[x] = FinalTCRTChainStat
                    elif ThisTCRTChainStat == "2A2B":
                        TCRTStatDict[x] = "doublet"
                    else:
                        TCRTStatDict[x] = "-"
            elif FinalTCRTChainStat == "2A2B":
                for x in TCRTBeMapTCRTList[t]:
                    ThisTCRTSetName = TCRTNameMapDictRaw[x]
                    ThisTCRTChainStat = getTCRXAXB(ThisTCRTSetName)

                    if ThisTCRTChainStat == "2A2B" and ThisTCRTSetName == FinalTCRTSetName:
                        TCRTStatDict[x] = "2A2B"
                    else:
                        TCRTStatDict[x] = "-"
            else:
                print "TCRT Chain Type error:", t, FinalTCRTSetName, FinalTCRTChainStat

        return TCRTStatDict

    def BarTCRNameAdj(BarTCRRawDict, TCRTNameMapDict, TCRTBarListDict2, XCRflag):
        # BarTCRRawDict,a barcode's Raw seq TCR.TCRTBarListDict2,a barcode finally belong to a TCRT.a barcode must belong to a unique TCRT
        # TCRSetName:[[AChain],[BChain]],V-CDR3

        def TCRChainAln(MChainList, BarChainSet, XCRflag):
            # input example:MChainList=["TRAV1:AA","TRAV2:BB"],BarChainSet = set(["TRAV3:D3:J3:CC"])
            # return:final view stri
            SList = []
            BarMapList = []
            BarUnMapList = []
            for i in BarChainSet:
                BarUnMapList.append(i)

            if len(MChainList) <= 2 and len(BarChainSet) <= 2:
                SList = []
                for x in MChainList:
                    xtemp = x.split(":")
                    xv = xtemp[0]
                    xcdr3 = xtemp[1]
                    flag = 0
                    print("MChainList:")
                    print(MChainList)
                    print("BarChainSet:")
                    print(BarChainSet)
                    for y in BarChainSet:
                        tempy = y.split(":")
                        yvgene = tempy[0]
                        ycdr3 = tempy[3]
                        if yvgene.find(xv) > -1 and ycdr3 == xcdr3:  # yvgene like TRAV1-2,xv like TRA1.cdr3 must ==
                            stri = "yvgene:%s xv:%s ycdr3:%s xcdr3:%s" % (yvgene, xv, ycdr3, xcdr3)
                            print(stri)
                            SList.append(y)
                            BarMapList.append(y)
                            BarUnMapList.remove(y)
                            flag = 1
                            break

                    if flag == 0:
                        SList.append("-")
            else:
                print "error:chains number > 2!"
                return False

            FList = []
            if len(BarUnMapList) == 0:
                for i in SList:
                    FList.append(i)

            while len(BarUnMapList) > 0:
                for i in SList:
                    if i == "-" and len(BarUnMapList) > 0:
                        Choose = BarUnMapList[0]
                        FList.append(Choose)
                        BarUnMapList.remove(Choose)
                    else:
                        FList.append(i)

                if len(BarUnMapList) > 0:
                    addList = []
                    for i in BarUnMapList:
                        FList.append(i)
                        addList.append(i)

                    for i in addList:
                        BarUnMapList.remove(i)

            if XCRflag == "TCR":
                fillNULL = "-\t-\t-\t-"
            elif XCRflag == "BCR":
                fillNULL = "-\t-\t-\t-\t-"
            else:
                print "XCRFlag error!", XCRflag
                return False
            ViewStri = ""
            c = 0
            for i in FList:  # FList:[],["XXX"],["-","XXX"],["-","-"],["XXX","-"],["XXX","YYY"]
                if i == "-":
                    if ViewStri != "":
                        ViewStri = "%s\t%s" % (ViewStri, fillNULL)
                    else:
                        ViewStri = "%s" % (fillNULL)
                    c += 1
                elif i != "":
                    ViewStri += "\t"
                    for p in i.split(":"):
                        ViewStri += p
                        ViewStri += "\t"
                    ViewStri = ViewStri.strip("\t")
                    c += 1
            if c < 2:
                tempstri = "%s\t" % (fillNULL)
                tempstri = tempstri * (2 - c)
                ViewStri = "%s\t%s" % (ViewStri, tempstri)
                ViewStri = ViewStri.strip("\t")

            return ViewStri

        # function TCRChainAln end.

        # BarTCRNameAdj main
        BarcodeTCRTDict = {}
        BarcodeTCRAdjDict = {}
        for t in TCRTBarListDict2:
            BarList = TCRTBarListDict2[t]
            for b in BarList:
                if b not in BarcodeTCRTDict:
                    BarcodeTCRTDict[b] = t
                else:
                    print "error in BarTCRNameAdj!barcode have mul TCRT"
                    return False

        if len(BarcodeTCRTDict) != len(BarTCRRawDict):
            print "error in BarTCRNameAdj!barcode num"
            return False

        for b in BarcodeTCRTDict:
            TCRT = BarcodeTCRTDict[b]
            TCRTSetName = TCRTNameMapDict[TCRT]

            TCRTCAList = list(TCRTSetName[0])
            TCRTCBList = list(TCRTSetName[1])

            BarRawTCRCA = BarTCRRawDict[b]["A"]
            BarRawTCRCB = BarTCRRawDict[b]["B"]

            CAStri = TCRChainAln(TCRTCAList, BarRawTCRCA, XCRflag)
            CBStri = TCRChainAln(TCRTCBList, BarRawTCRCB, XCRflag)

            TCRStri = "%s\t%s" % (CAStri, CBStri)
            BarcodeTCRAdjDict[b] = TCRStri

        return BarcodeTCRAdjDict
        # BarTCRNameAdj function end.

    def XCRGetSeq(TCRTMapTCRFDict, TCRTBarListDict, TCRTNameMapDict, BarTCRChainDict):
        TCRFChoBarListDict = {}
        TCRFSeqKeySortDict = {}
        TCRFOutLineDict = {}

        for t in TCRTBarListDict:
            TCRF = TCRTMapTCRFDict[t]
            ThisTCRTSetName = TCRTNameMapDict[t]
            BarList = TCRTBarListDict[t]
            TCRFChoBarListDict[TCRF] = []

            flag = 0
            for b in BarList:
                BarSetName = [BarTCRChainDict[b]["A"], BarTCRChainDict[b]["B"]]
                if BarSetName == ThisTCRTSetName:
                    for x in ThisTCRTSetName[0]:
                        stri = "%s\t%s" % (x, b)  # chain\tbarcode
                        TCRFChoBarListDict[TCRF].append(stri)
                    for x in ThisTCRTSetName[1]:
                        stri = "%s\t%s" % (x, b)  # chain\tbarcode
                        TCRFChoBarListDict[TCRF].append(stri)

                    flag = 1
                    break

            if flag == 0:
                while flag < 2:
                    for b in BarList:
                        BarSetName1 = BarTCRChainDict[b]["A"]
                        BarSetName2 = BarTCRChainDict[b]["B"]

                        if BarSetName1 == ThisTCRTSetName[0] and BarSetName2 != ThisTCRTSetName[1]:
                            for x in ThisTCRTSetName[0]:
                                stri = "%s\t%s" % (x, b)  # chain\tbarcode
                                TCRFChoBarListDict[TCRF].append(stri)
                            flag += 1
                        elif BarSetName1 != ThisTCRTSetName[0] and BarSetName2 == ThisTCRTSetName[1]:
                            for x in ThisTCRTSetName[1]:
                                stri = "%s\t%s" % (x, b)  # chain\tbarcode
                                TCRFChoBarListDict[TCRF].append(stri)
                            flag += 1
                        elif BarSetName1 == ThisTCRTSetName[0] and BarSetName2 == ThisTCRTSetName[1]:
                            print "error:", b, BarSetName1, BarSetName2, "TCRF:", BarSetName2
                    if flag < 2:
                        print "TCRF can't choose barcode!", TCRF
                        break

        # w = file("/home/xingjun/zdata1/TCRChooseBar.txt","w+")
        # for i in TCRFChoBarListDict:
        #    for y in TCRFChoBarListDict[i]:
        #        stri = "%s\t%s\n" % (i,y)
        #        w.write(stri)
        # w.close()
        return TCRFChoBarListDict

    # XCRGetSeq function end.

    # TCRAna2 main
    # get raw data
    print "get raw info start:"
    TCRFirstNameResult = TCRFirstName(BarTCRChainDict2, 1)
    TCRTNameMapDict = TCRFirstNameResult[0]
    TCRTNumDict = TCRFirstNameResult[1]
    TCRTBarListDict = TCRFirstNameResult[2]
    BarTCRTDict = TCRFirstNameResult[3]
    TCRTMapTCRTDict = {}

    TCRTNameMapDictRaw = copyNewDict(TCRTNameMapDict)
    TCRTNumDictRaw = copyNewDict(TCRTNumDict)

    AllBarTypeList = FromBarcodeGetType(BarTCRChainDict2)
    print("get raw info end.","TCRTNameMapDict:",len(TCRTNameMapDict),"TCRTNumDict:",len(TCRTNumDict),"TCRTBarListDict:",len(TCRTBarListDict),"TCRTMapTCRTDict:",len(TCRTMapTCRTDict),"TCRTNameMapDictRaw:",len(TCRTNameMapDictRaw),"TCRTNumDictRaw:",len(TCRTNumDictRaw),"BarTCRTDict:",len(BarTCRTDict))
    print("AllBarTypeList:",AllBarTypeList)

    # do
    print "TCR denove start:"
    TCRDenoveResult = TCRDenove(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict, TCRTNameMapDictRaw,
                                TCRTNumDictRaw)  # step1
    TCRTNameMapDict = TCRDenoveResult[0]
    TCRTNumDict = TCRDenoveResult[1]
    TCRTMapTCRTDict = TCRDenoveResult[2]
    TCRTNameMapDictRaw = TCRDenoveResult[3]
    TCRTNumDictRaw = TCRDenoveResult[4]
    print "TCR denovo end!"

    print "TCR merge start:"
    TCRMergeResult = TCRMerge(TCRTNameMapDict, TCRTNumDict, TCRTMapTCRTDict)  # step 2
    TCRTBeMapTCRTList = TCRMergeResult[0]
    TCRTNumDict = TCRMergeResult[1]
    TCRTMapTCRFDict = TCRMergeResult[2]  # one one map.because TCRTNumDict is now.
    TCRTBelongTCRTDict = TCRMergeResult[3]
    TCRTBarListDict2 = BarBelongFinal(TCRTBarListDict, TCRTBelongTCRTDict)
    print "TCRTBarListDict2:", len(TCRTBarListDict2), "TCRTBarListDict:", len(TCRTBarListDict)
    print "TCR merge end!"

    print "decide TCR stat:"
    TCRTStatDict = GetTCRStat(TCRTBeMapTCRTList, TCRTNameMapDictRaw)
    print "decide end!"

    print "TCR choose barcode:"
    TCRFChoBarListDict = XCRGetSeq(TCRTMapTCRFDict, TCRTBarListDict2, TCRTNameMapDict, BarTCRChainDict2)
    print "TCR choose barcode end!"

    print "Single Chain TCRT map To Normal TCRT:"
    if BarTCRChainDictSC != "F":  # consider Single Chains
        TCRFirstNameResult = TCRFirstName(BarTCRChainDictSC, 2)
        SCTCRTNameMapDict = TCRFirstNameResult[0]
        SCTCRTNumDict = TCRFirstNameResult[1]
        SCTCRTBarListDict = TCRFirstNameResult[2]
        BarSCTCRTDict = TCRFirstNameResult[3]

        SCMapToTCRResult = SCMapToTCR(SCTCRTNameMapDict, SCTCRTNumDict, TCRTNameMapDictRaw, TCRTNumDict)
        TCRTBeSCMapListDict = SCMapToTCRResult[0]
        SCTCRBelongTCRTDict = SCMapToTCRResult[1]
        SCTCRTBarListDict2 = BarBelongFinal(SCTCRTBarListDict, SCTCRBelongTCRTDict)  # key is TCRT!!!

        AllBarTypeList1 = FromBarcodeGetType(BarTCRChainDictSC)
        AllBarTypeList = list(set(AllBarTypeList + AllBarTypeList1))

    print "Single Chain TCRT map To Normal TCRT end!"

    # Barcode Raw TCR Name Adj
    print "barcode raw TCR name adj:"
    BarcodeTCRAdjDict1 = BarTCRNameAdj(BarTCRChainDictA, TCRTNameMapDict, TCRTBarListDict2, XCR)
    print "barcode raw TCR name end!"
    print "barcode raw SC TCR name adj:"  # select SCTCR barcode that only can map to TCRT
    ChoSCBarList = []
    RawSCTCRBarNum = len(BarTCRChainDictSCA)
    for i in SCTCRTBarListDict2:  # some SCTCRT can't map to TCRT or map to tow or more TCRTS.
        BarList = SCTCRTBarListDict2[i]
        for b in BarList:
            if b not in ChoSCBarList:
                ChoSCBarList.append(b)
            else:
                print "error:a SCTCRT barcode belong to two or more TCRT!", b
    print "raw seq SCTCRT barcode num:", RawSCTCRBarNum, "final SCTCRT barcode num:", len(ChoSCBarList)
    BarTCRChainDictSCCho = {}
    for b in ChoSCBarList:
        BarTCRChainDictSCCho[b] = BarTCRChainDictSCA[b]
    BarcodeTCRAdjDict2 = BarTCRNameAdj(BarTCRChainDictSCCho, TCRTNameMapDict, SCTCRTBarListDict2,
                                       XCR)  # SCTCRTBarListDict2's key is TCRT!
    print "barcode raw SC TCR name end!"
    # Barcode Raw TCR Name Adj end.

    # out table
    outFile = "%s/%s.%sTBelong.xls" % (workdir, sampleName, XCR)
    w = file(outFile, "w+")
    head = "XCRT\tNum\tXCRStat\tXCRid1\tMapToXCRT\tXCRid2\tFinalNum\n"
    w.write(head)
    for i in TCRTBelongTCRTDict:
        MapTo = TCRTBelongTCRTDict[i]
        if i in TCRTStatDict:
            TCRStat = TCRTStatDict[i]
        else:
            TCRStat = "-"
        stri = "%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (
        i, TCRTNumDictRaw[i], TCRStat, TCRSetNameToId(TCRTNameMapDictRaw[i]), MapTo,
        TCRSetNameToId(TCRTNameMapDictRaw[MapTo]), TCRTNumDict[MapTo])
        w.write(stri)
    w.close()

    outFile = "%s/%s.SC%sBelong.xls" % (workdir, sampleName, XCR)
    w = file(outFile, "w+")
    head = "SCXCRT\tNum\tXCRid1\tMapToXCRT\tXCRid2\n"
    w.write(head)
    for i in SCTCRBelongTCRTDict:
        MapTo = SCTCRBelongTCRTDict[i]
        stri = "%s\t%s\t%s\t%s\t%s\n" % (
        i, SCTCRTNumDict[i], TCRSetNameToId(SCTCRTNameMapDict[i]), MapTo, TCRSetNameToId(TCRTNameMapDictRaw[MapTo]))
        w.write(stri)
    w.close()
    # out table end.

    # TCRAna2 main end
    result = [TCRTNumDictRaw, TCRTNumDict, SCTCRTNumDict, TCRTNameMapDictRaw, SCTCRTNameMapDict, TCRTBeMapTCRTList,
              TCRTMapTCRFDict, TCRTBeSCMapListDict, TCRTBelongTCRTDict, TCRTBarListDict2, SCTCRTBarListDict2,
              AllBarTypeList, TCRTStatDict, BarTCRTDict, BarSCTCRTDict, BarcodeTCRAdjDict1, BarcodeTCRAdjDict2,
              TCRFChoBarListDict]
    return result


# TCRAna2 function end

def TCRSta(TCRTNumDictRaw, TCRTNumDict, SCTCRTNumDict, TCRTMapTCRFDict, TCRTNameMapDictRaw, SCTCRTNameMapDict,
           TCRTBeMapTCRTList, TCRTBeSCMapListDict, TCRTBelongTCRTDict, TCRTBarListDict2, SCTCRTBarListDict2,
           AllBarTypeList, TCRTStatDict, BarTCRTDict, BarSCTCRTDict, BarcodeTCRAdjDict1, BarcodeTCRAdjDict2):
    def StaChainTCR(TCRTNumDict, TCRTNumDictRaw, TCRTMapTCRFDict, key):
        ChainTCRTListNumDict = {}
        ChainTCRTListDict = {}
        ChainTCRTNameDict = {}

        for t in TCRTNumDict:
            TCRTSetName = TCRTNameMapDictRaw[t]
            if key == "CA":
                ThisChainSet = TCRTSetName[0]
            elif key == "CB":
                ThisChainSet = TCRTSetName[1]
            else:
                print "key error in StaChainTCR!CA or CB!"
                return False

            for x in ThisChainSet:
                if x not in ChainTCRTListDict:
                    ChainTCRTListDict[x] = []
                    ChainTCRTListNumDict[x] = []
                    ChainTCRTNameDict[x] = []

                    ChainTCRTListDict[x].append(TCRTMapTCRFDict[t])
                    ChainTCRTListNumDict[x].append(TCRTNumDict[t])
                    ChainTCRTNameDict[x].append(TCRSetNameToId(TCRTSetName))
                else:
                    ChainTCRTListDict[x].append(TCRTMapTCRFDict[t])
                    ChainTCRTListNumDict[x].append(TCRTNumDict[t])
                    ChainTCRTNameDict[x].append(TCRSetNameToId(TCRTSetName))

        # w = file(outFile,"w+")
        # head = "Chain\tXCR\tXCRInfo\tXCRNum\n"
        # w.write(head)
        outList = []
        for i in ChainTCRTListDict:
            stri = "%s\t%s\t%s\t%s\n" % (
            i, CombMulWords(ChainTCRTListDict[i], ","), CombMulWords(ChainTCRTNameDict[i], ","),
            CombMulWords(ChainTCRTListNumDict[i], ","))
            outList.append(stri)

        return outList

    # get TCRF List
    TCRFList = []
    TCRFMapTDict = {}
    TCRTTypeDisDict = {}
    TCRTTissuDisDict = {}

    AllBarTypeList2 = []
    for t in AllBarTypeList:
        AllBarTypeList2.append(t)
    for t in AllBarTypeList:
        stri = "%s-SC" % (t)
        AllBarTypeList2.append(stri)
    HeadTissuTypeStri = CombMulWords(AllBarTypeList2, "\t")

    for t in TCRTNumDict:
        TCRF = TCRTMapTCRFDict[t]
        if TCRF not in TCRFList:
            TCRFList.append(TCRF)
            TCRFMapTDict[TCRF] = t
        else:
            print "TCRF exists! in TCRFList", t, TCRF
    # get TCRF list end.

    # TCR every chain type dis
    for t in TCRTNumDict:
        NumA1B0 = 0
        NumA0B1 = 0
        NumA1B1 = 0
        NumA2B1 = 0
        NumA1B2 = 0
        NumA2B2 = 0

        ThisTCRTAllList = set(TCRTBeMapTCRTList[t])
        ThisTCRTSCList = []
        if t in TCRTBeSCMapListDict:
            ThisTCRTSCList += TCRTBeSCMapListDict[t]

        ThisTCRTAllBarList = TCRTBarListDict2[t]
        if t in SCTCRTBarListDict2:
            ThisTCRTAllSCBarList = SCTCRTBarListDict2[t]
        else:
            ThisTCRTAllSCBarList = []

        ThisTCRTBarTypeDisDict = BarListTypeDis(ThisTCRTAllBarList, ThisTCRTAllSCBarList, AllBarTypeList)

        for x in ThisTCRTAllList:
            TCRSetName = TCRTNameMapDictRaw[x]
            ChainType = getTCRXAXB(TCRSetName)
            if ChainType == "1A1B":
                NumA1B1 += TCRTNumDictRaw[x]
            elif ChainType == "2A1B":
                NumA2B1 += TCRTNumDictRaw[x]
            elif ChainType == "1A2B":
                NumA1B2 += TCRTNumDictRaw[x]
            elif ChainType == "2A2B":
                NumA2B2 += TCRTNumDictRaw[x]
            else:
                print "TCR type error:", x, ChainType, TCRSetName

        for x in ThisTCRTSCList:
            TCRSetName = SCTCRTNameMapDict[x]
            ChainType = getTCRXAXB(TCRSetName)
            if ChainType == "0A1B":
                NumA0B1 += SCTCRTNumDict[x]
            elif ChainType == "1A0B":
                NumA1B0 += SCTCRTNumDict[x]
            else:
                print "TCR type error:", x, ChainType, TCRSetName

        TCRNum1 = NumA1B1 + NumA2B1 + NumA1B2 + NumA2B2
        TCRNum2 = NumA0B1 + NumA1B0
        TCRNum3 = TCRNum1 + TCRNum2

        if TCRNum1 != TCRTNumDict[t]:
            print "warning TCR num!", t, TCRNum1, TCRTNumDict[t]

        TCRTTypeDisDict[t] = {"SC-A": NumA1B0, "SC-B": NumA0B1, "1A1B": NumA1B1, "2A1B": NumA2B1, "1A2B": NumA1B2,
                              "2A2B": NumA2B2, "TCRNum1": TCRNum1, "TCRNum2": TCRNum2, "TCRNum3": TCRNum3}
        TCRTTissuDisDict[t] = ThisTCRTBarTypeDisDict
    # TCR every chain type dis sta end.

    # Chain TCRT sta
    for t in TCRTNumDict:
        TCRF = TCRTMapTCRFDict[t]
        TCRTSetName = TCRTNameMapDictRaw[t]

    TCRTNumDictRaw, TCRTNumDict
    # all TCRT info table(include SC TCR)
    TCRTOutLinesDict = {}
    TCRTOutLinesHead = ""
    outFile = "%s/%s.%sAna2.xls" % (workdir, sampleName, XCR)
    w = file(outFile, "w+")

    if XCR == "TCR":
        head = "TCRT\tTCRTNum\tTCRid\tTCRStat\tTCRName\t1A1B\t1A2B\t2A1B\t2A2B\tTCRNum1\tSC-A\tSC-B\tTCRNum2\tTCRNum3\t"
        TCRTOutLinesHead = "TCRid\tTCRStat\tTCRName\t1A1B\t1A2B\t2A1B\t2A2B\tTCRNum1\tSC-A\tSC-B\tTCRNum2\tTCRNum3\t"
    elif XCR == "BCR":
        head = "BCRT\tBCRTNum\tBCRid\tBCRStat\tBCRName\t1A1B\t1A2B\t2A1B\t2A2B\tBCRNum1\tSC-A\tSC-B\tBCRNum2\tBCRNum3\t"
        TCRTOutLinesHead = "BCRid\tBCRStat\tBCRName\t1A1B\t1A2B\t2A1B\t2A2B\tBCRNum1\tSC-A\tSC-B\tBCRNum2\tBCRNum3\t"
    else:
        print "XCR flag error!", XCR
        return False
    head += HeadTissuTypeStri
    TCRTOutLinesHead += HeadTissuTypeStri
    head += "\n"
    w.write(head)

    SCTCRTMapTCRTDict = {}
    for x in TCRTBeSCMapListDict:
        ThisSCTCRTList = TCRTBeSCMapListDict[x]
        for y in ThisSCTCRTList:
            SCTCRTMapTCRTDict[y] = x

    # final TCRT
    for t in TCRTBelongTCRTDict:
        BelongTCRT = TCRTBelongTCRTDict[t]
        TCRF = TCRTMapTCRFDict[BelongTCRT]
        if t in TCRTNameMapDictRaw:
            TCRid = TCRSetNameToId(TCRTNameMapDictRaw[t])
        else:
            print "TCRT name can't find in TCRTNameMapDictRaw!", t
            return False

        if t in TCRTStatDict:
            TCRStat = TCRTStatDict[t]
        else:
            return False

        stri = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t" % (
        TCRid, TCRStat, TCRF, TCRTTypeDisDict[BelongTCRT]["1A1B"], TCRTTypeDisDict[BelongTCRT]["1A2B"],
        TCRTTypeDisDict[BelongTCRT]["2A1B"], TCRTTypeDisDict[BelongTCRT]["2A2B"],
        TCRTTypeDisDict[BelongTCRT]["TCRNum1"], TCRTTypeDisDict[BelongTCRT]["SC-A"],
        TCRTTypeDisDict[BelongTCRT]["SC-B"], TCRTTypeDisDict[BelongTCRT]["TCRNum2"],
        TCRTTypeDisDict[BelongTCRT]["TCRNum3"])
        for x in AllBarTypeList2:
            stri += str(TCRTTissuDisDict[BelongTCRT][x])
            stri += "\t"
        stri = stri.strip("\t")

        stri1 = "%s\t%s\t%s\n" % (t, TCRTNumDictRaw[t], stri)
        w.write(stri1)
        TCRTOutLinesDict[t] = stri  # {TCRT:ThisTCRToutLine}

    # SC TCR
    for t in SCTCRTMapTCRTDict:
        BelongTCRT = SCTCRTMapTCRTDict[t]
        TCRF = TCRTMapTCRFDict[BelongTCRT]
        if t in SCTCRTNameMapDict:
            TCRid = TCRSetNameToId(SCTCRTNameMapDict[t])
        else:
            print "TCRT name can't find in TCRTNameMapDictRaw!", t
            return False

        SCTCRTSetName = SCTCRTNameMapDict[t]
        SCTCRTType = getTCRXAXB(SCTCRTSetName)
        if SCTCRTType == "0A1B":
            TCRStat = "SC-B"
        elif SCTCRTType == "1A0B":
            TCRStat = "SC-A"
        else:
            TCRStat = "SC?"

        stri = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t" % (
        TCRid, TCRStat, TCRF, TCRTTypeDisDict[BelongTCRT]["1A1B"], TCRTTypeDisDict[BelongTCRT]["1A2B"],
        TCRTTypeDisDict[BelongTCRT]["2A1B"], TCRTTypeDisDict[BelongTCRT]["2A2B"],
        TCRTTypeDisDict[BelongTCRT]["TCRNum1"], TCRTTypeDisDict[BelongTCRT]["SC-A"],
        TCRTTypeDisDict[BelongTCRT]["SC-B"], TCRTTypeDisDict[BelongTCRT]["TCRNum2"],
        TCRTTypeDisDict[BelongTCRT]["TCRNum3"])
        for x in AllBarTypeList2:
            stri += str(TCRTTissuDisDict[BelongTCRT][x])
            stri += "\t"
        stri = stri.strip("\t")

        stri1 = "%s\t%s\t%s\n" % (t, SCTCRTNumDict[t], stri)
        w.write(stri1)
        TCRTOutLinesDict[t] = stri

    w.close()
    # all TCRT info table end.

    # output Barcode TCR info Table
    AllBarTCRTDict = {}
    SCTCRTBarNum = 0
    for t in SCTCRTBarListDict2:
        ThisSCTCRTBarList = SCTCRTBarListDict2[t]
        for b in ThisSCTCRTBarList:
            SCTCRT = BarSCTCRTDict[b]
            AllBarTCRTDict[b] = SCTCRT
            SCTCRTBarNum += 1
    for b in BarTCRTDict:
        AllBarTCRTDict[b] = BarTCRTDict[b]

    print "Output Barcode XCRT info Table:", "SCXCR barcode num:", SCTCRTBarNum, "Final XCRT barcode num:", len(
        BarTCRTDict)

    outFile = "%s/%s.Bar%sInfo.xls" % (workdir, sampleName, XCR)
    # head
    w = file(outFile, "w+")
    if XCR == "TCR":
        XCRChainName = "VA1\tDA1\tJA1\tCDR3A1\tVA2\tDA2\tJA2\tCDR3A2\tVB1\tDB1\tJB1\tCDR3B1\tVB2\tDB2\tJB2\tCDR3B2"
        head = "barcode\tTCRT\t%s\t%s\n" % (XCRChainName, TCRTOutLinesHead)
    elif XCR == "BCR":
        XCRChainName = "VA1\tDA1\tJA1\tCDR3A1\tCA1\tVA2\tDA2\tJA2\tCDR3A2\tCA2\tVB1\tDB1\tJB1\tCDR3B1\tCB1\tVB2\tDB2\tJB2\tCDR3B2\tCB2"
        head = "barcode\tBCRT\t%s\t%s\n" % (XCRChainName, TCRTOutLinesHead)
    else:
        print "XCRFlagg error!", XCR
        return False
    w.write(head)
    # head end.
    for b in AllBarTCRTDict:
        BarTCRT = AllBarTCRTDict[b]
        if b in BarcodeTCRAdjDict1:
            BarTCRName = BarcodeTCRAdjDict1[b]
        elif b in BarcodeTCRAdjDict2:
            BarTCRName = BarcodeTCRAdjDict2[b]
        else:
            print "barcode can't find TCR Raw Name!", b
            return False

        if BarTCRT in TCRTOutLinesDict:
            stri = "%s\t%s\t%s\t%s\n" % (b, BarTCRT, BarTCRName, TCRTOutLinesDict[BarTCRT])
            w.write(stri)
        else:
            print "barcode's TCRT not in BarTCRTRawDict!", b, BarTCRT
            return False
    w.close()
    # Barcode TCRinfo Table end.

    # Chain Info sta
    ChainInfoLineList = []
    ChainInfoLineList = StaChainTCR(TCRTNumDict, TCRTNumDictRaw, TCRTMapTCRFDict, "CA")
    ChainInfoLineList += StaChainTCR(TCRTNumDict, TCRTNumDictRaw, TCRTMapTCRFDict, "CB")
    outFile = "%s/%s.%sChainSta.xls" % (workdir, sampleName, XCR)
    if XCR == "TCR":
        head = "Chain\tTCR\tTCRInfo\tTCRNum\n"
    elif XCR == "BCR":
        head = "Chain\tBCR\tBCRInfo\tBCRNum\n"
    else:
        return False
    w = file(outFile, "w+")
    w.write(head)
    for i in ChainInfoLineList:
        w.write(i)
    w.close()
    # Chain info sta end.


# TCR Sta end.

def XCRSeq(BarTCRRawInfoDict, BarKeyFaDict, TCRFChoBarListDict, XCR, sampleName, workdir):
    # TCRFChoBarListDict: TCR:[TRBV13:CASSLETSGSAGANVLTF\tN3_Blood_GTCCTCAGTCCGTGAC-1,...]

    XCRRawSeqDict = {}  # key:XCRName\tV:CDR3\tbarcode
    XCRRawSeqDictList = []

    # sort XCR
    XCRList = TCRFChoBarListDict.keys()
    XCRListSort = PoZheNameSort(XCRList)
    # sort XCR end

    # get TCR raw seq
    for i in XCRListSort:  # TCR-1,BCR-1
        for l in TCRFChoBarListDict[i]:  # l,barcode. key:TRBV13:CASSLETSGSAGANVLTF\tN3_Blood_GTCCTCAGTCCGTGAC-1. This VGene is big class.
            findflag = 0
            tempstri = l.split("\t")
            chainList = tempstri[0].split(":")
            barcode = [tempstri[1]]
            keylist = barcode + chainList
            for s in BarKeyFaDict:
                rightNum = 0
                for k in keylist:
                    if s.find(k) > -1:
                        rightNum += 1
                if rightNum == len(keylist):
                    RawSeq = BarKeyFaDict[s]
                    findflag = 1
                    break
            # pattern = r"(?=.*" + r")(?=.*".join(keylist) + r")"
            # for fa in BarKeyFaDict:
            #     match = re.search(pattern, fa)
            #     if match:
            #         RawSeq = BarKeyFaDict[fa]

            newkey = "%s\t%s" % (i, l)
            if findflag == 1:
                XCRRawSeqDict[newkey] = RawSeq
            else:
                XCRRawSeqDict[newkey] = "-"
            XCRRawSeqDictList.append(newkey)
    # get TCR seq end!

    outFile = "%s/%s.%sFaSeq.xls" % (workdir, sampleName, XCR)
    w = file(outFile, "w+")
    if XCR == "TCR":

        head = "TCR\tTCRindex\tChoBar\tChainInfo\tRawSeq\n"
        w.write(head)

        for i in XCRRawSeqDictList:  # for every TCR

            temp = i.split("\t")
            TCRName = temp[0]
            TCRVGene = temp[1].split(":")[0]
            TCRCDR3 = temp[1].split(":")[1]
            ThisBar = temp[2]
            ThisRawSeq = XCRRawSeqDict[i]

            BarChainInfo = SearchChainInfo(BarTCRRawInfoDict[ThisBar], TCRVGene)  # V:D:J:CDR3
            stri = "%s\t%s\t%s\t%s\t%s\n" % (TCRName, TCRName, ThisBar, BarChainInfo, ThisRawSeq)
            w.write(stri)

        w.close()

    elif XCR == "BCR":
        head = "BCR\tChain\tChooseBarcode\tseq\n"
        w.write(head)

        for i in XCRRawSeqDictList:
            stri = "%s\t%s\n" % (i, XCRRawSeqDict[i])
            w.write(stri)
        w.close()
    else:
        print "XCR error!"
        return False


# XCRSeq end!


# -----------------------------------------------------------------
# main

# get info
if XCRFlag == "1":
    BarTCRstatDict = fromTableGetMap2(TCRAna1, "barcode", "TCRstat")
    BarTCRidDict = fromTableGetMap2(TCRAna1, "barcode", "TCRid")  #
elif XCRFlag == "2":
    BarTCRstatDict = fromTableGetMap2(TCRAna1, "barcode", "BCRstat")
    BarTCRidDict = fromTableGetMap2(TCRAna1, "barcode", "BCRid")

BarTCRResult = getBarTCRDataDict(BarTCRidDict, 1, "T")  # get 1A1B,1A2B,2A1B,2A2B XCR!
BarTCRChainDictA = BarTCRResult[0]  # vdjcdr3
BarTCRChainDict2 = BarTCRResult[1]  # v-cdr3
BarTCRResult = getBarTCRDataDict(BarTCRidDict, 2, "T")  # get 0A1B,1A0B XCR!
BarTCRChainDictSCA = BarTCRResult[0]  # vdjcdr3
BarTCRChainDictSC = BarTCRResult[1]  # v-cdr3

# if give a filter barcode list,then filter BarTCRChainDictSC
if CellListFile != "F":
    DelNum1 = 0
    DelNum2 = 0
    FinalBarList = []
    f = open(CellListFile)
    line = f.readline()
    while line:
        line = line.strip("\n")
        if line not in FinalBarList:
            FinalBarList.append(line)
        line = f.readline()
    f.close()

    BarTCRChainDict2BarList = BarTCRChainDict2.keys()
    BarTCRChainDictSCBarList = BarTCRChainDictSC.keys()
    for i in BarTCRChainDict2BarList:
        if i not in FinalBarList:
            BarTCRChainDict2.pop(i)
            BarTCRChainDictA.pop(i)
            DelNum1 += 1
    for i in BarTCRChainDictSCBarList:
        if i not in FinalBarList:
            BarTCRChainDictSC.pop(i)
            BarTCRChainDictSCA.pop(i)
            DelNum2 += 1
    print "Filter CellList:", "del Stand-TCR barcode num:", DelNum1, "del SC-TCR barcode num:", DelNum2, "raw Stand-TCR barcode num:", len(
        BarTCRChainDict2BarList), "raw SC-TCR barcode num:", len(BarTCRChainDictSCBarList)
# get info end.

# TCR ana
TCRAna2Result = TCRAna2(BarTCRChainDict2, BarTCRChainDictSC, BarTCRChainDictA, BarTCRChainDictSCA, XCR)
TCRTNumDictRaw = TCRAna2Result[0]
TCRTNumDict = TCRAna2Result[1]
SCTCRTNumDict = TCRAna2Result[2]
TCRTNameMapDictRaw = TCRAna2Result[3]
SCTCRTNameMapDict = TCRAna2Result[4]
TCRTBeMapTCRTList = TCRAna2Result[5]
TCRTMapTCRFDict = TCRAna2Result[6]
TCRTBeSCMapListDict = TCRAna2Result[7]
TCRTBelongTCRTDict = TCRAna2Result[8]
TCRTBarListDict2 = TCRAna2Result[9]
SCTCRTBarListDict2 = TCRAna2Result[10]
AllBarTypeList = TCRAna2Result[11]
TCRTStatDict = TCRAna2Result[12]
BarTCRTDict = TCRAna2Result[13]
BarSCTCRTDict = TCRAna2Result[14]
BarcodeTCRAdjDict1 = TCRAna2Result[15]
BarcodeTCRAdjDict2 = TCRAna2Result[16]
TCRFChoBarListDict = TCRAna2Result[17]
# TCR ana end.

# TCR sta
print "TCR sta and create tables:"
TCRSta(TCRTNumDictRaw, TCRTNumDict, SCTCRTNumDict, TCRTMapTCRFDict, TCRTNameMapDictRaw, SCTCRTNameMapDict,
       TCRTBeMapTCRTList, TCRTBeSCMapListDict, TCRTBelongTCRTDict, TCRTBarListDict2, SCTCRTBarListDict2, AllBarTypeList,
       TCRTStatDict, BarTCRTDict, BarSCTCRTDict, BarcodeTCRAdjDict1, BarcodeTCRAdjDict2)
print "TCR sta and create tables end!"
# TCR sta end.

# XCR get Seq
if XCRSeqFile != "F":
    BarKeyFaDict = fromTableGetMap2(XCRSeqFile, "key", "fa")  # key:barcode:V:D:J:CDR3,VGene contain sub calss
    XCRSeq(BarTCRChainDictA, BarKeyFaDict, TCRFChoBarListDict, XCR, sampleName, workdir)

# XCR get Seq end
